int cmp(const void* p1, const void* p2)
{
    return *((int*)p1) > *((int*)p2);
}
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {

    int top = 0;
    int** parr = (int**)malloc(sizeof(int*) * 18000);
    if (numsSize < 3)
    {
        *returnSize = 0;
        return parr;
    }
    qsort(nums, numsSize, sizeof(int), cmp);
    for (int i = 0; i < numsSize - 2; i++)
    {
        if (nums[i] > 0)
        {
            break;
        }
        if (i > 0 && nums[i] == nums[i - 1])
        {
            continue;
        }
        int left = i + 1;
        int right = numsSize - 1;
        while (left < right)
        {
            int sum = nums[left] + nums[right] + nums[i];
            if (sum > 0)
            {
                right--;
            }
            else if (sum < 0)
            {
                left++;
            }
            else
            {
                int* arr = (int*)malloc(sizeof(int) * 3);
                arr[0] = nums[i]; arr[1] = nums[left]; arr[2] = nums[right];
                parr[top++] = arr;
                while (left < right && nums[left] == nums[left + 1])
                {
                    left++;
                }
                while (left < right && nums[right] == nums[right - 1])
                {
                    right--;
                }
                left++;
                right--;
            }
        }
    }
    *returnSize = top;
    *returnColumnSizes = (int*)malloc(sizeof(int) * top);
    for (int i = 0; i < top; i++)
    {
        (*returnColumnSizes)[i] = 3;
    }
    return parr;
}